﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Text.RegularExpressions;
using System.ServiceModel.Channels;
using System.Configuration;
using WeSContactData.model;
using WeSContactData.util;
using System.Data;
using System.Runtime.InteropServices;


namespace WeSContactData
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class WeSContactData : IWeSContactData
    {

        [DllImport("Kernel32.dll", SetLastError = true)]
        static extern IntPtr OpenEvent(uint dwDesiredAccess, bool bInheritHandle, string lpName);

        [DllImport("kernel32.dll")]
        static extern bool SetEvent(IntPtr hEvent);

        const uint STANDARD_RIGHTS_REQUIRED = 0x000F0000;
        const uint SYNCHRONIZE = 0x00100000;
        const uint EVENT_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3);
        const UInt32 INFINITE = 0xFFFFFFFF;

        public bool wakeUpWiSContactData()
        {
            IntPtr hdlOpen;
            hdlOpen = OpenEvent(EVENT_ALL_ACCESS, false, "Global\\WiSContactData");
            if (hdlOpen != IntPtr.Zero)
            {
                SetEvent(hdlOpen); //Wake up
                return true;
            }
            else
                return false;
        }

        public ContactDataResultStatus requestIP()
        {

            OperationContext context = OperationContext.Current;
            MessageProperties messageProperties = context.IncomingMessageProperties;
            RemoteEndpointMessageProperty endpointProperty =
              messageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;


            if (!checkAuthenticatedIp(endpointProperty.Address))
            {
                return new ContactDataResultStatus
                {
                    statusCode = ContactDataResultStatus.STATUS_UNALLOW_IP_CODE,
                    statusText = string.Format(ContactDataResultStatus.STATUS_UNALLOW_IP_TEXT, endpointProperty.Address)

                };

            }
            else
            {
                return new ContactDataResultStatus
                {
                    statusCode = ContactDataResultStatus.STATUS_VALID_TOKEN_CODE,
                    statusText = ContactDataResultStatus.STATUS_VALID_TOKEN_TEXT
                };
            }
        }

        private bool checkAuthenticatedIp(string iP)
        {
            string whiteIP = ConfigurationManager.AppSettings["WhiteIPs"];
            whiteIP = whiteIP.Trim();
            string[] result = whiteIP.Split(';');

            foreach (string sub in result)
            {
                string t = sub.Trim();
                if (iP == t)
                    return true;

            }
            return false;

        }
        public bool checkEmailAd(string address)
        {
            address = address.Trim();
            if (address == "")
            {
                return false;
            }
            else
            {

                string[] result = Regex.Split(address, ",");
                int flag = 0;
                foreach (string sub in result)
                {
                    string t = sub.Trim();
                    if (t != "")
                    {
                        flag = 1;
                        break;
                    }
                }
                if (flag == 0)
                {
                    return false;
                }
                foreach (string sub in result)
                {
                    string t = sub.Trim();

                    if (t != "" && Regex.IsMatch(t, @"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z") == false)
                    {
                        return false;
                    }

                }
            }
            return true;
        }
       
        public WeSContactDataEnqueueResult Enqueue(ContactData contactData)
        {
            ContactDataResultStatus request = requestIP();
            if (request.statusCode == 0)
            {

                try
                {
                    if (checkEmailAd(contactData.email) == true)
                    {
                        object[,] parameter = { 
                                        {"@name",contactData.name},
                                        {"@email",contactData.email},
                                        {"@mobile",contactData.mobile},
                                        {"@msgTypeId",contactData.msgTypeId},
                                        {"@msgContent",contactData.msgContent},
                                        {"@remark",contactData.remark},
                                        //{"@beginTime",contactData.beginTime},
                                        //{"@endTime",contactData.endTime},
                                        //{"@status",contactData.status},
                                        {"@enqueueTime",DateTime.Now.ToString("yyyyMMddHHmmss")}              
                                      };

                        DB.exec("insert into ContactData (Name, Email, Mobile, MsgTypeId, MsgContent, Remark, Status, EnqueueTime) values (@name, @email, @mobile, @msgTypeId, @msgContent, @remark,'New' ,@enqueueTime);", parameter);
                        wakeUpWiSContactData();
                        return new WeSContactDataEnqueueResult
                        {
                            contactDataResult = new ContactDataResultStatus
                            {
                                statusCode = ContactDataResultStatus.STATUS_VALID_TOKEN_CODE,
                                statusText = ContactDataResultStatus.STATUS_VALID_TOKEN_TEXT
                            }
                        };
                    }
                    else
                    {
                        return new WeSContactDataEnqueueResult
                        {
                            contactDataResult = new ContactDataResultStatus
                            {
                                statusCode = ContactDataResultStatus.STATUS_INVALID_EMAIL_CODE,
                                statusText = ContactDataResultStatus.STATUS_INVALID_EMAIL_TEXT
                            }
                        };
                    }

                }
                catch (Exception ex)
                {
                    return new WeSContactDataEnqueueResult
                    {
                        contactDataResult = new ContactDataResultStatus
                        {
                            statusCode =500,
                            statusText = ex.Message
                    
                        }
                    };
                }
            }
            else
            {

                return new WeSContactDataEnqueueResult
                {
                    contactDataResult = request
                };
            }           
        }

        public WeSContactDataDequeueResult Dequeue()
        {
            try
            {
                ContactData temp = new ContactData();
                DataTable dt = null;
                dt = DB.getData("select top 1 * from ContactData where DequeueTime is null");
                if (dt.Rows.Count == 0)
                {
                    return new WeSContactDataDequeueResult
                    {
                        contactData = null,
                        contactDataResult = new ContactDataResultStatus
                        {
                            statusCode = ContactDataResultStatus.STATUS_OUT_DEQUEUE_CODE,
                            statusText = ContactDataResultStatus.STATUS_OUT_DEQUEUE_TEXT
                        }

                    };
                }
                else
                {
                    temp.id = Convert.ToInt32(dt.Rows[0]["Id"]);
                    temp.beginTime = dt.Rows[0]["BeginTime"].ToString();
                    temp.email = dt.Rows[0]["Email"].ToString();
                    temp.endTime = dt.Rows[0]["EndTime"].ToString();
                    temp.enqueueTime = dt.Rows[0]["EnqueueTime"].ToString();
                    temp.mobile = dt.Rows[0]["Mobile"].ToString();
                    temp.msgContent = dt.Rows[0]["MsgContent"].ToString();
                    temp.msgTypeId = Convert.ToInt32(dt.Rows[0]["MsgTypeId"]);
                    temp.name = dt.Rows[0]["Name"].ToString();
                    temp.remark = dt.Rows[0]["Remark"].ToString();
                    temp.status = dt.Rows[0]["Status"].ToString();
                    object[,] parameter = { 
                                        {"@id",temp.id},
                                        {"@dequeueTime",DateTime.Now.ToString("yyyyMMddHHmmss")}
                                                       
                                      };
                    DB.exec("update ContactData Set DequeueTime =@dequeueTime where Id =@id;", parameter);
                    return new WeSContactDataDequeueResult
                    {
                        contactData = temp,
                        contactDataResult = new ContactDataResultStatus
                        {
                            statusCode = ContactDataResultStatus.STATUS_VALID_TOKEN_CODE,
                            statusText = ContactDataResultStatus.STATUS_VALID_TOKEN_TEXT
                        }

                    };
                }
            }
            catch ( Exception ex)
            {

                return new WeSContactDataDequeueResult
                {
                    contactDataResult = new ContactDataResultStatus
                    {
                        statusCode = 500,
                        statusText = ex.Message
                    }
                };
            }

        }


    }
}
